package com.habdqn.studentmanager.service.impl;

import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.habdqn.studentmanager.bean.Dictionary;
import com.habdqn.studentmanager.bean.SysLog;
import com.habdqn.studentmanager.bean.SysMenu;
import com.habdqn.studentmanager.bean.Teacher;
import com.habdqn.studentmanager.bean.condition.DateCondition;
import com.habdqn.studentmanager.constant.Constant;
import com.habdqn.studentmanager.constant.LogType;
import com.habdqn.studentmanager.exception.StudentException;
import com.habdqn.studentmanager.mapper.DictionaryMapper;
import com.habdqn.studentmanager.mapper.MenuMapper;
import com.habdqn.studentmanager.mapper.SysLogMapper;
import com.habdqn.studentmanager.mapper.TeacherMapper;
import com.habdqn.studentmanager.service.SystemService;
import com.habdqn.studentmanager.service.TeacherService;
import com.habdqn.studentmanager.util.AESUtil;
import com.habdqn.studentmanager.util.DateUtil;
import com.habdqn.studentmanager.util.MD5Util;
import com.habdqn.studentmanager.util.ProjectUtil;
import com.habdqn.studentmanager.util.SystemLogger;

/**
 * @author Administrator
 * 
 *         2017年5月15日
 * 
 */
@Service
public class SystemServiceImpl implements SystemService {

	private static Logger logger = LoggerFactory.getLogger(SystemServiceImpl.class);

	@Resource
	private SystemLogger systemLogger;

	@Resource
	private TeacherMapper teacherMapper;

	@Resource
	private TeacherService teacherService;

	@Resource
	private DictionaryMapper dictMapper;

	@Resource
	private MenuMapper menuMapper;

	@Resource
	private SysLogMapper sysLogMapper;

	@Override
	@Transactional
	public void login(Teacher bean, boolean isRemember) {
		// 防止走到其他条件分支
		bean.setId(null);

		Teacher obj = null;
		try {
			// MD5(账号+密码明文)加密保存
			bean.setPassword(MD5Util.getMD5(bean.getAccount() + bean.getPassword()));
			obj = teacherMapper.find(bean);
		}
		catch (RuntimeException e) {
			logger.error("登陆失败", e);
			throw new StudentException("系统异常", e);
		}
		catch (NoSuchAlgorithmException e) {
			logger.error("没有合适的加密算法", e);
			throw new StudentException("没有合适的加密算法", e);
		}
		catch (UnsupportedEncodingException e) {
			logger.error("错误的编码", e);
			throw new StudentException("错误的编码", e);
		}

		if (null == obj || null == obj.getAccount()) {
			logger.debug("没有查询到 account为: {} 的账号", bean.getAccount());
			throw new StudentException("账号或密码错误");
		}

		ProjectUtil.removeSessionAttr(Constant.CURRENT_TEACHER);
		ProjectUtil.setSessionAttr(Constant.CURRENT_TEACHER, obj);

		if (isRemember) {
			String cipherText = AESUtil.encrypt(obj.getAccount());
			// 清空现有的
			ProjectUtil.addCookie(Constant.TOKEN, null, 0, true);
			ProjectUtil.addCookie(Constant.TOKEN, cipherText);
		}
		systemLogger.record(LogType.LoginType, "正常登录");
	}

	@Override
	public void exit() {

		Teacher current = ProjectUtil.getCurrentUser();
		
		if (null == current) {
			throw new StudentException("登录信息为空，请先登录");
		}
		
		systemLogger.record(LogType.ExitType, "退出登录:" + current.getAccount());
		
		HttpSession session = ProjectUtil.getSessions();
		if (null != session) {
			session.removeAttribute(Constant.CURRENT_TEACHER);
		}
		ProjectUtil.addCookie(Constant.TOKEN, null, 0, true);
	}

	@Override
	public PageInfo<SysLog> findLogList(SysLog bean, DateCondition dateCondition, Integer pageNum, Integer pageSize) {

		// 设置结束时间为最后时刻
		if (null != dateCondition && null != dateCondition.getEndDate()) {
			Date endDate = dateCondition.getEndDate();
			DateUtil.addHours(23, endDate);
			DateUtil.addMinutes(59, endDate);
			DateUtil.addSeconds(59, endDate);
		}

		try {
			PageHelper.startPage(pageNum, pageSize);
			return new PageInfo<SysLog>(sysLogMapper.findList(bean, dateCondition));
		}
		catch (Exception e) {
			logger.error("system error", e);
			throw new StudentException("查询日志列表失败");
		}
	}

	@Override
	public void addMenu(SysMenu bean) {

	}

	@Override
	public void updateMenu(SysMenu bean) {

	}

	@Override
	public void delMenu(SysMenu bean) {

	}

	@Override
	public void addDict(Dictionary bean) {

	}

	@Override
	public void updateDict(Dictionary bean) {

	}

	@Override
	public void delDict(Dictionary bean) {

	}

	@Override
	public Dictionary findDict(Dictionary bean) {
		return null;
	}

	@Override
	public List<Dictionary> findDictList(Dictionary bean) {

		try {
			return dictMapper.findList(bean);
		}
		catch (Exception e) {
			logger.error("system error", e);
			throw new StudentException("查询字典列表失败", e);
		}
	}

	@Override
	public void changePassword(String oldPassword, String newPassword) {
		Teacher teacher = ProjectUtil.getCurrentUser();

		// 数据是否正常
		if (null == teacher.getAccount()) {
			throw new StudentException("获取账号id失败, 请重新登陆");
		}

		// 作为条件类
		Teacher condition = new Teacher();
		condition.setAccount(teacher.getAccount());
		condition.setPassword(oldPassword);

		// 查询密码是否正确
		condition = teacherMapper.find(condition);

		if (null == condition) {
			throw new StudentException("密码错误，请重新输入");
		}

		logger.debug("account: " + condition.getAccount());

		condition.setPassword(newPassword);
		try {
			teacherMapper.update(condition);
		}
		catch (Exception e) {
			logger.error("更新密码失败", e);
			throw new StudentException("更新密码失败", e);
		}

		systemLogger.record(LogType.UpdateType, "修改密码");
	}

	@Override
	public List<SysMenu> findMenuList(SysMenu bean) {

		List<SysMenu> topMenu = null;

		try {
			topMenu = menuMapper.findList(bean);
			// 查询关联的子菜单
			for (SysMenu menu : topMenu) {
				List<SysMenu> subMenus = menuMapper.findList(menu);
				menu.setSubMenus(subMenus);
			}
		}
		catch (Exception e) {
			logger.error("system error", e);
			throw new StudentException("系统异常", e);
		}

		return topMenu;
	}

	@Override
	public void login(String token) {
		String teacherAccount = AESUtil.decrypt(token);

		Teacher teacher = new Teacher();
		try {
			teacher.setAccount(teacherAccount);
			teacher = teacherMapper.find(teacher);
		}
		catch (RuntimeException e) {
			logger.debug("登录失败", e);
			throw new StudentException("登录失败", e);
		}

		// 查询出来的与查询条件不一致
		if (!StringUtils.equals(teacherAccount, teacher.getAccount())) {
			throw new StudentException("登录失败");
		}

		ProjectUtil.removeSessionAttr(Constant.CURRENT_TEACHER);
		ProjectUtil.setSessionAttr(Constant.CURRENT_TEACHER, teacher);
		systemLogger.record(LogType.LoginType, "通过Cookie登录");
	}

	@Override
	public void register(Teacher bean) {

		try {
			// MD5(账号+密码明文)加密保存
			String password = bean.getAccount() + bean.getPassword();
			password = MD5Util.getMD5(password);
			bean.setPassword(password);
			teacherMapper.insert(bean);
			systemLogger.record(bean, LogType.AddType, "自主注册");
		}
		catch (RuntimeException e) {
			logger.error("注册失败", e);
			throw new StudentException("注册失败", e);
		}
		catch (NoSuchAlgorithmException e) {
			logger.error("没有合适的加密算法", e);
			throw new StudentException("没有合适的加密算法", e);
		}
		catch (UnsupportedEncodingException e) {
			logger.error("错误的编码", e);
			throw new StudentException("错误的编码", e);
		}
	}
}
